package cn.xz.zgsg.base

import android.annotation.SuppressLint
import android.content.Context
import android.content.res.Configuration
import android.os.Bundle
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.InputMethodManager
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.setPadding
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.Lifecycle
import cn.xz.zgsg.R
import cn.xz.zgsg.bean.EventBusMessage
import cn.xz.zgsg.util.AppHelper
import cn.xz.zgsg.util.EventBusUtils
import com.trello.rxlifecycle4.components.support.RxAppCompatDialogFragment
import org.greenrobot.eventbus.Subscribe


/**
 * 弹窗基类
 */
abstract class BaseDialogRxFragment (
    private var setEventBus: Boolean = false //是否注册EventBus,默认不注册
): RxAppCompatDialogFragment() {

    /**
     * 从调用show方法开始 到dismiss结束
     * 用于标识是否已经开始显示该窗口 防止连续重复显示报重复添加
     */
    private var isShowing: Boolean = false

    private var isRootViewHasCreated: Boolean = false//为了复用rootview 防止重复加载试图增加的标记

    /**
     * 记录是不是用户积极手动弹出 只对order的弹窗有效
     */
    private var positiveShow: Boolean = false

    /**
     * 该弹窗是否需要排序（-1默认不需要 设置的话必须大于0）
     */
    open fun order(): Int = -1

    /**
     * 需要全屏 默认需要
     */
    open fun needFullScreen(): Boolean {
        return true
    }

    private var rootContainer: View? = null

    open fun getRootView(inflater: LayoutInflater?, container: ViewGroup?, layoutId: Int): View {

        if (rootContainer == null) {
            isRootViewHasCreated = false
            rootContainer = inflater!!.inflate(layoutId, container)

        } else {

            if (null != rootContainer!!.parent) {
                (rootContainer!!.parent as ViewGroup).removeView(rootContainer)
            }
            isRootViewHasCreated = true
        }
        return rootContainer!!
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        val layoutId = getLayoutId()
        if (layoutId <= 0) {
            throw NotImplementedError("设置的layoutId 必须是真实存在的")
        }
        if (setEventBus){
            EventBusUtils.register(this)
        }
        return getRootView(inflater, container, layoutId)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        if (!isRootViewHasCreated) {
            initViews()
        } else {
            reCoverView()
        }
    }

    /**
     * 返回容器需要的layout文件
     */
    abstract fun getLayoutId(): Int

    abstract fun initViews()

    /**
     * 当已经初始化view 再次显示view时调用
     */
    open fun reCoverView() {

    }

    @SuppressLint("WrongConstant")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        //初始化队列弹窗相关
        val act = activity
        //只有符合排队的窗口才会初始化mOrderViewModel
        if (order() > 0 && (!positiveShow) && act is AppCompatActivity) {
           // mOrderViewModel = ViewModelProvider(act).get(OrderViewModel::class.java)
        }
        val orientation = activity?.resources?.configuration?.orientation

        if (orientation == Configuration.ORIENTATION_PORTRAIT) {
            setStyle(DialogFragment.STYLE_NO_FRAME, R.style.BottomDialogTransparent)
        } else {
            if (needFullScreen()) {
                setStyle(DialogFragment.STYLE_NO_FRAME, R.style.dialog_fullScreen)
            } else {
                setStyle(DialogFragment.STYLE_NO_FRAME, R.style.BottomDialogTransparent)
            }
        }
    }

    /**
     * 配置弹窗参数 由于基本上每个弹窗都要配置宽高和位置 这里写个接口方法  还有就是控制它的执行时机在[setWindowAnimations]之前 以让默认动画生效
     */
    abstract fun configDialog()

    /**
     * 宽度显示比例
     */
    fun setDialogSize(
        gravity: Int = Gravity.BOTTOM,
        width: Int = ViewGroup.LayoutParams.MATCH_PARENT,
        height: Int = ViewGroup.LayoutParams.WRAP_CONTENT,
        padding: Int = 0
    ) {
        val window = dialog?.window ?: return
        val params = window.attributes
        window.decorView.setPadding(AppHelper.dp2px(padding))
        params.gravity = gravity
        if (width > 0) {
            params.width = AppHelper.dp2px(width)
        } else if (ViewGroup.LayoutParams.WRAP_CONTENT == width || ViewGroup.LayoutParams.MATCH_PARENT == width) {
            params.width = width
        }
        if (height > 0) {
            params.height = AppHelper.dp2px(height)
        } else if (ViewGroup.LayoutParams.WRAP_CONTENT == height || ViewGroup.LayoutParams.MATCH_PARENT == height) {
            params.height = height
        }
        window.attributes = params
    }

    /**
     * 宽度显示比例
     */
    fun setDialogSize(
        gravity: Int = Gravity.BOTTOM,
        marginWidth: Int,
        height: Int = ViewGroup.LayoutParams.WRAP_CONTENT
    ) {
        val window = dialog?.window ?: return
        val params = window.attributes
        params.gravity = gravity
        params.width =
            window.windowManager.defaultDisplay.width - AppHelper.dp2px(marginWidth.toFloat()) * 2
        if (height > 0) {
            params.height = AppHelper.dp2px(height.toFloat())
        } else if (ViewGroup.LayoutParams.WRAP_CONTENT == height || ViewGroup.LayoutParams.MATCH_PARENT == height) {
            params.height = height
        }
        window.attributes = params
    }

    /**
     * 宽度显示比例
     */
    fun setDialogSize(
        gravity: Int = Gravity.BOTTOM,
        marginWidth: Int,
        height: Int = ViewGroup.LayoutParams.WRAP_CONTENT,
        offsetX: Int = 0,
        offsetY: Int = 0
    ) {
        val window = dialog?.window ?: return
        val params = window.attributes
        params.gravity = gravity
        params.x = offsetX
        params.y = AppHelper.dp2px(offsetY.toFloat())
        params.width =
            window.windowManager.defaultDisplay.width - AppHelper.dp2px(marginWidth.toFloat()) * 2
        if (height > 0) {
            params.height = AppHelper.dp2px(height.toFloat())
        } else if (ViewGroup.LayoutParams.WRAP_CONTENT == height || ViewGroup.LayoutParams.MATCH_PARENT == height) {
            params.height = height
        }
        window.attributes = params
    }

    /**
     * 宽度显示比例,引导弹窗
     */
    var isYDDialog = false
    fun setYDDialogSize(
        gravity: Int = Gravity.TOP,
        width: Int = ViewGroup.LayoutParams.MATCH_PARENT,
        height: Int = ViewGroup.LayoutParams.WRAP_CONTENT,
        offsetX: Int = 0,
        offsetY: Int = 0
    ) {
        val window = dialog?.window ?: return
        val params = window.attributes
        params.gravity = gravity
        params.x = offsetX
        params.y = AppHelper.dp2px(offsetY.toFloat())
        if (width > 0) {
            params.width = AppHelper.dp2px(width)
        } else if (ViewGroup.LayoutParams.WRAP_CONTENT == width || ViewGroup.LayoutParams.MATCH_PARENT == width) {
            params.width = width
        }
        if (height > 0) {
            params.height = AppHelper.dp2px(height.toFloat())
        } else if (ViewGroup.LayoutParams.WRAP_CONTENT == height || ViewGroup.LayoutParams.MATCH_PARENT == height) {
            params.height = height
        }
        window.attributes = params
        isYDDialog = true
    }

    // 滑出动画，默认从底部滑入，底部滑出
    open fun setWindowAnimations() {
        val window = dialog?.window ?: return
        val params = window.attributes

        when (params.gravity) {
            Gravity.CENTER -> {
                window.setWindowAnimations(R.style.dialog_center_open_ani)
            }
            Gravity.TOP -> {
                if (isYDDialog){
                    isYDDialog = false
                    window.setWindowAnimations(R.style.dialog_center_open_ani)
                }else{
                    window.setWindowAnimations(R.style.dialog_top_top_style)
                }
            }
            Gravity.BOTTOM -> {
                window.setWindowAnimations(R.style.dialog_bottom_bottom_style)
            }
            else -> {
                window.setWindowAnimations(R.style.dialog_bottom_bottom_style)
            }
        }

    }

    open fun needEnterAnimation(): Boolean {
        return true
    }

    override fun onStart() {
        configDialog()
        if (needEnterAnimation())
            setWindowAnimations()
        super.onStart()
    }

    open fun initEventBus(message: EventBusMessage){}

    @Subscribe
    fun onSubscriberEvent(message: EventBusMessage) {
        initEventBus(message)
    }


    override fun onDestroy() {
        super.onDestroy()
        isShowing = false
        if (setEventBus){
            EventBusUtils.unRegister(this)
        }
    }


    override fun show(manager: FragmentManager, tag: String?) {
        try {
            //每次先判断是否已经被添加
            if (isAdded || isShowing) {
//                dismiss()
            } else {
                if (!manager.isStateSaved) {
                    isShowing = true
                    super.show(manager, tag)
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()

        }


    }




    override fun dismiss() {
        //Can not perform this action after onSaveInstanceState
        // com.julun.huanque.common.base.BaseDialogFragment.dismiss(BaseDialogFragment.kt:248)
        //针对报这个错的处理
        //
        if (!lifecycle.currentState.isAtLeast(Lifecycle.State.CREATED)) {
            return
        }
        try {
            hideSoftInput()
        } catch (e: Exception) {
            e.printStackTrace()
        }
        super.dismissAllowingStateLoss()
        isShowing = false
    }



    override fun dismissAllowingStateLoss() {
        super.dismissAllowingStateLoss()
        isShowing = false
    }



    private fun hideSoftInput(){
        val imm = context?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        imm.hideSoftInputFromWindow(dialog?.currentFocus?.windowToken, 0)
    }

}